package com.myzl.coal.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.myzl.coal.domain.CommandRecord;
import com.myzl.coal.dto.SendCmdDTO;
import com.myzl.coal.mapper.CommandRecordMapper;
import com.myzl.coal.service.ICommandRecordService;
import com.myzl.coal.utils.CalculationUtils;
import com.myzl.common.enums.CommandStatusEnum;
import com.myzl.common.utils.DateUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * 命令下发记录Service业务层处理
 *
 * @author myzl
 * @date 2022-10-26
 */
@Service
@Slf4j
@Data
public class CommandRecordServiceImpl extends ServiceImpl<CommandRecordMapper, CommandRecord> implements ICommandRecordService {
    private final CommandRecordMapper commandRecordMapper;
    public final MongoTemplate mongoTemplate;

    /**
     * 查询命令下发记录
     *
     * @param id 命令下发记录主键
     * @return 命令下发记录
     */
    @Override
    public CommandRecord selectCommandRecordById(String id) {
        return commandRecordMapper.selectCommandRecordById(id);
    }

    @Override
    public boolean success(String id) {
        return this.success(id,null);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean success(String commandId, String callBackCmd) {
        Update update = new org.springframework.data.mongodb.core.query.Update();
        update.set("commandStatus",CommandStatusEnum.SUCCESS.getCode());
        if (Objects.nonNull(callBackCmd)) {
            update.set("callBackCmd",callBackCmd);
        }
        // 更新查找到的第一条
        mongoTemplate.updateFirst(Query.query(Criteria.where("id").is(commandId)), update, CommandRecord.class);
        return true;
    }

    @Override
    public boolean fail(String id) {
        return this.fail(id,null);
    }

    @Override
    public boolean fail(String commandId, String callBackCmd) {
        Update update = new org.springframework.data.mongodb.core.query.Update();
        update.set("commandStatus",CommandStatusEnum.FAIL.getCode());
        if (Objects.nonNull(callBackCmd)) {
            update.set("callBackCmd",callBackCmd);
        }
        // 更新查找到的第一条
        mongoTemplate.updateFirst(Query.query(Criteria.where("id").is(commandId)), update, CommandRecord.class);

        return true;
    }

    @Override
    public CommandRecord selectByDevice(CommandRecord commandRecord) {

        LambdaQueryWrapper<CommandRecord> wrapper = new LambdaQueryWrapper();
        wrapper.eq(CommandRecord::getDeviceId, commandRecord.getDeviceId());
        wrapper.eq(CommandRecord::getDeviceType, commandRecord.getDeviceType());
        wrapper.eq(CommandRecord::getCommandStatus, CommandStatusEnum.EXECUTE.getCode());
        CommandRecord result = commandRecordMapper.selectOne(wrapper);
        return result;
    }

    /**
     * 查询命令下发记录列表
     *
     * @param commandRecord 命令下发记录
     * @return 命令下发记录
     */
    @Override
    public List<CommandRecord> selectCommandRecordList(CommandRecord commandRecord) {
        return commandRecordMapper.selectCommandRecordList(commandRecord);
    }

    /**
     * 新增命令下发记录
     *
     * @param commandRecord 命令下发记录
     * @return 结果
     */
    @Override
    public int insertCommandRecord(CommandRecord commandRecord) {
        commandRecord.setCreateTime(DateUtils.getNowDate());
        return commandRecordMapper.insertCommandRecord(commandRecord);
    }

    @Override
    public CommandRecord insertCommandRecord(SendCmdDTO sendCmdDTO) {
        CommandRecord commandRecord = new CommandRecord();
        BeanUtils.copyProperties(sendCmdDTO,commandRecord);
        commandRecord.setSendCmd(sendCmdDTO.getCommandStr());
        commandRecord.setCommand(sendCmdDTO.getAddress());
        commandRecord.setCommandStatus(CommandStatusEnum.EXECUTE.getCode());
//        insertCommandRecord(commandRecord);
        commandRecord.setCreateTime(DateUtils.getNowDate());
        mongoTemplate.insert(commandRecord);
        sendCmdDTO.setMessageId(commandRecord.getId());
        return commandRecord;
    }

    @Override
    public boolean commandResult(String messageId) {
        //判断读取成功
        while (true) {
//            CommandRecord commandRecord = selectCommandRecordById(messageId);
            CommandRecord commandRecord = mongoTemplate.findById(messageId, CommandRecord.class);
            if (Objects.equals(commandRecord.getCommandStatus(), CommandStatusEnum.SUCCESS.getCode())) {
                return true;
            }
            if (Objects.equals(commandRecord.getCommandStatus(), CommandStatusEnum.FAIL.getCode())) {
                return false;
            }
            CalculationUtils.sleepSeconds(true, 1);
        }
    }

    /**
     * 修改命令下发记录
     *
     * @param commandRecord 命令下发记录
     * @return 结果
     */
    @Override
    public int updateCommandRecord(CommandRecord commandRecord) {
        commandRecord.setUpdateTime(DateUtils.getNowDate());
        return commandRecordMapper.updateCommandRecord(commandRecord);
    }

    /**
     * 批量删除命令下发记录
     *
     * @param ids 需要删除的命令下发记录主键
     * @return 结果
     */
    @Override
    public int deleteCommandRecordByIds(String[] ids) {
        return commandRecordMapper.deleteCommandRecordByIds(ids);
    }

    /**
     * 删除命令下发记录信息
     *
     * @param id 命令下发记录主键
     * @return 结果
     */
    @Override
    public int deleteCommandRecordById(String id) {
        return commandRecordMapper.deleteCommandRecordById(id);
    }
}
